package com.sky.service.impl;

import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.User;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkSpaceService;
import com.sky.vo.*;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    WorkSpaceService workSpaceService;

    @Override
    public TurnoverReportVO turnoverStatistics(LocalDateTime begin, LocalDateTime end) {
        end = end.plusHours(23)
                .plusMinutes(59)
                .plusSeconds(59);
        List<Orders> orders = orderMapper.turnoverStatistics(begin, end);
        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        Map<LocalDate, BigDecimal> map = new HashMap<>();
        for (Orders order : orders){
           if (!map.containsKey(order.getOrderTime().toLocalDate())){
               map.put(order.getOrderTime().toLocalDate(), order.getAmount());
           }
           // 如果map中存在该日期，则将金额累加到该日期对应的金额上
            else {
                map.put(order.getOrderTime().toLocalDate(), map.get(order.getOrderTime().toLocalDate()).add(order.getAmount()));
            }
        }
        Set<LocalDate> localDates = map.keySet();
       //将localDates按照日期排序
        localDates.stream().sorted().forEach(localDate -> {
            if (turnoverReportVO.getDateList()==null && turnoverReportVO.getTurnoverList()==null){
                turnoverReportVO.setDateList(localDate.toString());
                turnoverReportVO.setTurnoverList(map.get(localDate).toString());
            }else {
                turnoverReportVO.setDateList(turnoverReportVO.getDateList()+","+localDate.toString());
                turnoverReportVO.setTurnoverList(turnoverReportVO.getTurnoverList()+","+map.get(localDate).toString());
            }
        });
        return turnoverReportVO;
    }

    @Override
    public UserReportVO userStatistics(LocalDateTime beginDateTime, LocalDateTime endDateTime) {
        UserReportVO userReportVO = new UserReportVO();
        LocalDateTime nowTime = beginDateTime;
        while (nowTime.isBefore(endDateTime.plusDays(1))){
            if(userReportVO.getDateList()==null){
                userReportVO.setDateList(nowTime.toLocalDate().toString());
            }else {
                userReportVO.setDateList(userReportVO.getDateList()+","+nowTime.toLocalDate().toString());
            }

            //获取这个时间段之前注册的用户的总数
            Integer totalInNowTime = userMapper.getTotalUserInNowTime(nowTime);
            if(userReportVO.getTotalUserList()==null){
                userReportVO.setTotalUserList(totalInNowTime.toString());
            }else {
                userReportVO.setTotalUserList(userReportVO.getTotalUserList()+","+totalInNowTime.toString());
            }
            //获取当天的注册用户数量
            Integer newUserInNowTime = userMapper.getNewUsers(nowTime.plusDays(-1), nowTime);
            if(userReportVO.getNewUserList()==null){
                userReportVO.setNewUserList(newUserInNowTime.toString());
            }else {
                userReportVO.setNewUserList(userReportVO.getNewUserList()+","+newUserInNowTime.toString());
            }
            nowTime = nowTime.plusDays(1);
        }
        return userReportVO;
    }

    @Override
    public SalesTop10ReportVO top10(LocalDateTime beginDateTime, LocalDateTime endDateTime) {
        //查询这个时间段的所有order_detail
        List<OrderDetail> orderDetails = orderDetailMapper.findByOrderTime(beginDateTime, endDateTime);
        //用map集合来给每一种菜品计数
        Map<String, Integer> map = new HashMap<>();
        for (OrderDetail orderDetail : orderDetails){
            if (!map.containsKey(orderDetail.getName())){
                map.put(orderDetail.getName(), orderDetail.getNumber());
            }else {
                map.put(orderDetail.getName(), map.get(orderDetail.getName())+orderDetail.getNumber());
            }
        }
        //遍历map集合
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        SalesTop10ReportVO salesTop10ReportVO = new SalesTop10ReportVO();
        LinkedHashSet<Map.Entry<String, Integer>> collect = entries.stream().sorted((o1, o2) -> o2.getValue() - o1.getValue()).collect(Collectors.toCollection(LinkedHashSet::new));
        for (int i=0 ;i <10;i++){
            if (salesTop10ReportVO.getNameList()==null && salesTop10ReportVO.getNumberList()==null){
                salesTop10ReportVO.setNameList(collect.stream().toList().get(i).getKey());
                salesTop10ReportVO.setNumberList(collect.stream().toList().get(i).getValue().toString());
            }else {
                salesTop10ReportVO.setNameList(salesTop10ReportVO.getNameList()+","+collect.stream().toList().get(i).getKey());
                salesTop10ReportVO.setNumberList(salesTop10ReportVO.getNumberList()+","+collect.stream().toList().get(i).getValue().toString());
            }
        }
        return salesTop10ReportVO;
    }

    @Override
    public OrderReportVO ordersStatistics(LocalDateTime beginDateTime, LocalDateTime endDateTime) {
        OrderReportVO orderReportVO = new OrderReportVO();
        List<Orders> orders = orderMapper.finALlInTime(beginDateTime, endDateTime);
        Integer count = orders.size();
        Integer effectiveCount = orderMapper.turnoverStatistics(beginDateTime, endDateTime).size();
        orderReportVO.setTotalOrderCount(count);
        orderReportVO.setValidOrderCount(effectiveCount);
        orderReportVO.setOrderCompletionRate(effectiveCount.doubleValue()/count.doubleValue());
        LocalDateTime nowTime = beginDateTime;
        while (nowTime.isBefore(endDateTime.plusDays(1))){
            if(orderReportVO.getDateList()==null){
                orderReportVO.setDateList(nowTime.toLocalDate().toString());
            }else {
                orderReportVO.setDateList(orderReportVO.getDateList()+","+nowTime.toLocalDate().toString());
            }
            List<Orders> orders1 = orderMapper.finALlInTime(nowTime.plusDays(-1), nowTime);
            List<Orders> orders2 = orderMapper.turnoverStatistics(nowTime.plusDays(-1), nowTime);
            if(orderReportVO.getOrderCountList()==null && orderReportVO.getValidOrderCountList()==null){
                orderReportVO.setOrderCountList(orders1.size()+"");
                orderReportVO.setValidOrderCountList(orders2.size()+"");
            }else {
                orderReportVO.setOrderCountList(orderReportVO.getOrderCountList()+","+orders1.size());
                orderReportVO.setValidOrderCountList(orderReportVO.getValidOrderCountList()+","+orders2.size());
            }
            nowTime = nowTime.plusDays(1);
        }
        return orderReportVO;
    }

    @Override
    public void export(HttpServletResponse response) {
        //获取模板文件的文件对象
        InputStream resourceAsStream = this.getClass().getResourceAsStream("/template/运营数据报表模板.xlsx");
        //创建一个Excel表格对象
        try {
            XSSFWorkbook sheets = new XSSFWorkbook(resourceAsStream);
            //获取进30天的概览数据
            BusinessDataVO businessDataVO = workSpaceService.businessData( LocalDate.now().minusDays(30), LocalDate.now().minusDays(1));
            XSSFSheet sheet = sheets.getSheet("Sheet1");
            XSSFRow row = sheet.getRow(3);
            row.getCell(2).setCellValue(businessDataVO.getTurnover());
            row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessDataVO.getNewUsers());
            row = sheet.getRow(4);
            row.getCell(2).setCellValue(businessDataVO.getValidOrderCount());
            row.getCell(4).setCellValue(businessDataVO.getUnitPrice());

            //获取30天日期对应的数据
            int order_row=0;
            LocalDate indexTime = LocalDate.now().minusDays(1);
            while (!indexTime.isBefore(LocalDate.now().minusDays(30))){
                //获取这一天的数据
                BusinessDataVO businessDataVO1 = workSpaceService.businessData(indexTime, indexTime);
                XSSFRow order_row1 = sheet.getRow(7+order_row);
                order_row1.getCell(1).setCellValue(indexTime.toString());
                order_row1.getCell(2).setCellValue(businessDataVO1.getTurnover());
                order_row1.getCell(3).setCellValue(businessDataVO1.getValidOrderCount());
                order_row1.getCell(4).setCellValue(businessDataVO1.getOrderCompletionRate());
                order_row1.getCell(5).setCellValue(businessDataVO1.getUnitPrice());
                order_row1.getCell(6).setCellValue(businessDataVO1.getNewUsers());
                order_row++;
                indexTime = indexTime.plusDays(-1);
            }

            ServletOutputStream outputStream = response.getOutputStream();
            sheets.write(outputStream);
            //关闭资源
            sheets.close();
            outputStream.close();
            resourceAsStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
